﻿using GrapeCity.Forguncy.CellTypes;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Vant.CellTypes;

namespace Vant.WpfControls.DrawingObject
{
    /// <summary>
    /// Interaction logic for TabHeaderDrawingObject.xaml
    /// </summary>
    public partial class TabHeaderDrawingObject : UserControl
    {
        Tabs _tabs;
        IDrawingHelper _drawingHelper;
        CellTypeViewModelStyle _cellStyle;

        public TabHeaderDrawingObject(Tabs tabs, CellTypeViewModelStyle cellStyle, ICellInfo cell, IDrawingHelper drawingHelper)
        {
            _tabs = tabs;
            _drawingHelper = drawingHelper;
            _cellStyle = cellStyle;
            InitializeComponent();
        }

        protected override void OnRender(DrawingContext drawingContext)
        {
            var items = CreateItemViewModel();
            var height = _tabs.type == "line" ? 44 : 38;
            var margin = _tabs.shrink ? 16 : 24;
            if (_tabs.type == "card")
            {
                margin++;
            }
            double wholeMargin = _tabs.type == "line" ? 8 : 16 ;
            var cellSize = _drawingHelper.GetImageCellSize();

            var wholeWidth = cellSize.Width - wholeMargin * 2;
            if(wholeWidth < 0)
            {
                return;
            }
            var textFormats = CreateFormatedText(items, margin, wholeWidth);

            try
            {
                if (_tabs.type == "line")
                {
                    drawingContext.PushClip(new RectangleGeometry(new Rect(cellSize)));
                }
                else
                {
                    drawingContext.PushClip(new RectangleGeometry(new Rect(wholeMargin, 0, wholeWidth, cellSize.Height)));
                }
                drawingContext.DrawRectangle(_drawingHelper.GetBrush(_tabs.background ?? "white"), null, new Rect(0, 0, cellSize.Width, height));

                var startX = wholeMargin;
                for (int i = 0; i < textFormats.Count; i++)
                {
                    bool isSelected = i == 0;
                    var formatedText = textFormats[i];
                    var textWidth = formatedText.Width;
                    var itemWidth = textWidth + margin;
                    if (formatedText.MaxTextWidth > 0)
                    {
                        textWidth = Math.Min(formatedText.Width, formatedText.MaxTextWidth);
                        itemWidth = formatedText.MaxTextWidth + margin;
                    }
                    if (_tabs.type == "card")
                    {
                        var brush = isSelected ? _drawingHelper.GetBrush(_tabs.color) : null;
                        var rectWidth = itemWidth;
                        if(startX  + rectWidth > wholeWidth + wholeMargin)
                        {
                            rectWidth = wholeWidth + wholeMargin - startX;
                        }
                        if(rectWidth <= 0)
                        {
                            break;
                        }
                        drawingContext.DrawRectangle(brush, new Pen(_drawingHelper.GetBrush(_tabs.color), 1), new Rect(startX, 0, rectWidth, height));
                    }
                    drawingContext.DrawText(textFormats[i], new Point(startX + (itemWidth - textWidth) / 2, (height - formatedText.Height) / 2));

                    if (_tabs.type == "line" && _tabs.lineWidth > 0 && isSelected)
                    {
                        var pen = new Pen(_drawingHelper.GetBrush(_tabs.color), _tabs.lineHeight);
                        var lineWidth = _tabs.lineWidth;
                        if (_tabs.lineWidth > _tabs.lineHeight)
                        {
                            pen.StartLineCap = PenLineCap.Round; // StartLineCap 和 EndLineCap 会导致线段变长，所以要减去长出来的部分
                            pen.EndLineCap = PenLineCap.Round;
                            lineWidth -= _tabs.lineHeight;
                        }

                        var y = height - _tabs.lineHeight / 2;
                        var start = startX + (itemWidth - lineWidth) / 2;
  
                        drawingContext.DrawLine(pen, new Point(start, y), new Point(start + lineWidth, y));
                    }

                    startX += itemWidth;
                }
            }
            finally
            {
                drawingContext.Pop();
            }

            base.OnRender(drawingContext);
        }

        private List<FormattedText> CreateFormatedText(List<ItemViewModel> items, int margin, double wholeWidth)
        {
            var formatedText = items.Select(i =>
            {
                return new FormattedText(
                    i.title,
                    CultureInfo.CurrentUICulture,
                    FlowDirection.LeftToRight,
                    new Typeface(i.fontFamily, FontStyles.Normal, FontWeights.Normal, FontStretches.Normal),
                    _cellStyle.FontSize,
                    i.foreColor,
                    96d);
            }).ToList();

            var shrink = _tabs.shrink;
            if (!shrink)
            {
                var totalWidth = formatedText.Sum(i => i.Width + margin);
                if (totalWidth > wholeWidth)
                {
                    shrink = true;
                }
            }
            if (!shrink)
            {
                var itemWidth = wholeWidth / items.Count;
                var maxTextWidth = itemWidth - margin;
                foreach (var textFormat in formatedText)
                {
                    textFormat.MaxTextHeight = textFormat.Height;
                    textFormat.MaxTextWidth = maxTextWidth;
                    if (_tabs.ellipsis)
                    {
                        textFormat.Trimming = TextTrimming.CharacterEllipsis;
                    }
                    else
                    {
                        textFormat.Trimming = TextTrimming.None;
                    }
                }
            }

            return formatedText;
        }

        private List<ItemViewModel> CreateItemViewModel()
        {
            var tabItems = _tabs.tabs.OfType<Tab>().Select(i => i.title).ToList();
            if (tabItems.Count == 0)
            {
                for (int i = 0; i < 3; i++)
                {
                    tabItems.Add(Properties.Resources.Tabs_DefaultName + (i + 1));
                }
            }

            List<ItemViewModel> items = new List<ItemViewModel>();

            for (int i = 0; i < tabItems.Count; i++)
            {
                bool isSelected = i == 0;
                var itemViewModel = new ItemViewModel()
                {
                    title = tabItems[i],
                    fontFamily = _cellStyle.FontFamily,
                };

                if (isSelected)
                {
                    if (_tabs.titleActiveColor != null)
                    {
                        itemViewModel.foreColor = _cellStyle.Foreground ?? _drawingHelper.GetBrush(_tabs.titleActiveColor);
                    }
                    else
                    {
                        if (_tabs.type == "line")
                        {
                            itemViewModel.foreColor = _cellStyle.Foreground ?? _drawingHelper.GetBrush("#323233");
                        }
                        else
                        {
                            itemViewModel.foreColor = _cellStyle.Foreground ?? Brushes.White;
                        }
                    }
                }
                else
                {
                    if (_tabs.titleInactiveColor != null)
                    {
                        itemViewModel.foreColor = _cellStyle.Foreground ?? _drawingHelper.GetBrush(_tabs.titleInactiveColor);
                    }
                    else
                    {
                        if (_tabs.type == "line")
                        {
                            itemViewModel.foreColor = _cellStyle.Foreground ?? _drawingHelper.GetBrush("#646566");
                        }
                        else
                        {
                            itemViewModel.foreColor = _cellStyle.Foreground ?? _drawingHelper.GetBrush(_tabs.color);
                        }
                    }
                }

                items.Add(itemViewModel);
            }

            return items;
        }

        class ItemViewModel
        {
            public string title { get; set; }
            public FontFamily fontFamily { get; set; }
            public Brush foreColor { get; set; }
        }
    }
}
